<?php

require_once dirname(__FILE__).'/../../../../../lib/nusoap/nusoap.php';

/**
 * render actions.
 *
 * @package    ems1
 * @subpackage render
 * @author     Jacobo Martínez
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */

class renderActions extends sfActions
{
    // This is the sub-set of cabilities obtained using Tera-WURFL that will be
    // used for rendering the site.
    protected $capabilities = array(
        'brand_name',
        'model_name',
        'is_wireless_device',
        'viewport_supported',
        'resolution_width',
        'resolution_height',
        'dual_orientation',
        'jpg',
        'oma_support',
        'video',
        'progressive_download',
        'playback_3gpp',
        'playback_mp4',
        'streaming_video',
        'streaming_3gpp',
        'streaming_mp4',
        'mp3'
    );

    protected $capabilitiesForRender = array();

    protected function getUserAgentCapabilities()
    {
        $ua = WurflSupport::getUserAgent(); // get the user agent
        // instantiate the Tera-WURFL object
        $wurflObj = new TeraWurfl();
        // Indicates if the user agent was found
        $matched = false;
        // Get the capabilities of the current client.
        // Load device capabilities, returns true if matching device was found else return false
        $matched = $wurflObj->getDeviceCapabilitiesFromAgent($ua, true);

        // Now we select a sub-set of capabilities that are going to be used for rendering.
        // This array will contain the values for each capability in $capabilities for the
        // current user-agent/device, the values will be obtained using Tera-WURFL
        $this->capabilitiesForRender = array();
        foreach ($this->capabilities as $capability) {
            $this->capabilitiesForRender[$capability] = $wurflObj->getDeviceCapability($capability);
        }

        return $matched;
    }

    /**
     * This function returns a boolean value.
     * True if the device screen is equal or bigger than 320px*240px (width,height),
     * False otherwise.
     *
     * This function uses the capabilities determined above so make sure that are initialized
     * before executing this function.
     */
    protected function hasBigScreen()
    {
        if($this->capabilitiesForRender['resolution_width'] >= 320 && $this->capabilitiesForRender['resolution_height'] >= 240){
            return true;
        } else {
            return false;
        }
    }

    /**
     *  This function uses de User-Agent capabilities to redirect to a traditional
     *  Website if the url was given or to display a page with the message:
     *  "Only available for wireless devices."
     *
     *  @param $portal EmsPortal
     *  @param $is_wireless boolean - wheather or not the user-agent is a wireless device
     *
     *  @return void
     */
    protected function redirectIfNotWirelessDevice(EmsPortal $portal, $is_wireless)
    {
        if(!$is_wireless){
            $routing = sfContext::getInstance()->getRouting();
            if($this->portal->getWebsiteUrl() == ''){
                $this->redirect($routing->generate('render_not_wireless_device',$portal));
            } else {
                $this->redirect($portal->getWebsiteUrl());
            }
        }
    }

    public function executeRenderBlank()
    {
        $this->setLayout('blank');
    }

    public function executeRenderNotWirelessDevice(sfWebRequest $request)
    {
        $this->portal = $this->getRoute()->getObject();
    }

    public function executeRenderHomeSection(sfWebRequest $request)
    {
        $this->portal = $this->getRoute()->getObject();

        $this->getUserAgentCapabilities();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }
        
        $this->section = $this->portal->getHomeSection();

        $this->hasBigScreen = $this->hasBigScreen();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        $this->elements = $this->getSectionElements();

        $this->pager = new sfDoctrinePager(
            'EmsContent',
            $this->section->getMaxContentsPerPage()
        );
        $this->pager->setQuery($this->section->getEnabledAndPublishedContentsQuery());
        $this->pager->setPage($request->getParameter('page', 1));
        $this->pager->init();

        $this->updateStatisticsVisits($request, $this->portal, $this->section);

        $this->setTemplate('renderSection');
    }

    public function executeRenderSection(sfWebRequest $request)
    {
        $this->section = $this->getRoute()->getObject();
        
        $this->portal = $this->section->getPortal();
        
        $this->getUserAgentCapabilities();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        if(!$this->section->getIsEnabled() || !$this->section->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_section_unavailable', $this->section));
        }

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }

        $this->hasBigScreen = $this->hasBigScreen();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        $this->elements = $this->getSectionElements();

        if($this->section->getType()->getType() == 'Register'){
            
            $this->for_download = $request->getParameter('for_download',false);

            $this->for_user_autenthication = $request->getParameter('for_user_autenthication',false);

            $this->prepareRegisterSection($this->for_user_autenthication, $request->getParameter('key_value', null));

            if($this->for_download){
                $this->content = Doctrine::getTable('EmsContent')->find($request->getParameter('content_id'));
            }
        } else {
            if($this->section->getType()->getType() == 'News' && $this->section->getNewsSection()->getUsesExternalFeed()) {
                $wsdl = $this->section->getNewsSection()->getWebserviceFeedUrl();
                $client = new nusoap_client($wsdl, 'wsdl');

                $this->page = $request->getParameter('page', 1);

                $param = array(
                    'page' => $this->page,
                    'maxPerPage' => $this->section->getMaxContentsPerPage(),
                    );
                $ws_results = $client->call('WSGetNewsFeed', $param);

                $this->total_pages = $ws_results['totalPages'];
                
                unset ($ws_results['totalPages']);

                $this->news = $ws_results;
                
                $this->have_to_paginate = $this->total_pages > 1;
                $this->has_prev = $this->have_to_paginate && $this->page > 1;
                $this->has_next = $this->have_to_paginate && $this->page < $this->total_pages;
            } else {
                $this->pager = new sfDoctrinePager(
                    'EmsContent',
                    $this->section->getMaxContentsPerPage()
                );
                $this->pager->setQuery($this->section->getEnabledAndPublishedContentsQuery());
                $this->pager->setPage($request->getParameter('page', 1));
                $this->pager->init();
            }
        }
        $this->updateStatisticsVisits($request, $this->portal, $this->section);
    }

    protected function prepareRegisterSection($for_user_autenthication, $key_value = null)
    {
        foreach ($this->elements as $key => $element){
            if($element->getType()->getType() == 'Form'){
                if($for_user_autenthication){
                    $form = $this->createUserAuthenticationForm($element);
                } else {
                    $form = $this->createForm($element, $key_value);
                }
                
                $this->elementForm = $element;
                $this->form = $form;
                $this->form_position = $key;
                
                unset ($this->elements[$key]);
                
                break;
            }
        }
    }

    protected function createForm(EmsElement $element, $key_field_value = null)
    {
        $register = new EmsRegister();
        $register->setForm($element->getForm());

        foreach ($element->getForm()->getEnabledFields() as $key => $field) {
            $value = new EmsValue();
            $value->setField($field);

            if($field->getIsKey() && !is_null($key_field_value)){
                $value->setValue($key_field_value);
            }

            $register->getValues()->add($value,$key);
        }

        return new EmsRegisterForm($register, array('for_user_autenthication' => false));
    }

    protected function createUserAuthenticationForm(EmsElement $element)
    {
        $register = new EmsRegister();
        $register->setForm($element->getForm());

        $value = new EmsValue();
        $value->setField($element->getForm()->getKeyField());

        $register->getValues()->add($value);

        return new EmsRegisterForm($register, array('for_user_authentication' => true));
    }

    public function executeRenderContent(sfWebRequest $request)
    {
        $this->getUserAgentCapabilities();
        
        $this->content = $this->getRoute()->getObject();
        
        $this->section = $this->content->getSection();

        $this->portal = $this->section->getPortal();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        if(!$this->content->getIsEnabled() || !$this->content->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_content_unavailable', $this->content));
        }

        if(!$this->section->getIsEnabled() || !$this->section->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_section_unavailable', $this->section));
        }

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }

        $this->hasBigScreen = $this->hasBigScreen();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        if($this->portal->getUsesContentComments()){
            $this->setCommentsPagerAndForm($request);
        }

        if($this->content->getType()->getType() == 'Image'){
            $this->best = $this->content->getImage()->getBestFitImage(
                    $this->capabilitiesForRender['resolution_width'], $this->capabilitiesForRender['resolution_height']);
            if(!$this->capabilitiesForRender['jpg'] || !$this->best){
                $this->setTemplate('renderContentFailure');
            }
        }

        $this->updateStatisticsVisits($request, $this->portal, null, $this->content);
    }

    public function executeRenderContentExternal(sfWebRequest $request)
    {
        $this->section = $this->getRoute()->getObject();

        $this->portal = $this->section->getPortal();

        $this->getUserAgentCapabilities();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        if(!$this->section->getIsEnabled() || !$this->section->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_section_unavailable', $this->section));
        }

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }

        $this->hasBigScreen = $this->hasBigScreen();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        $wsdl = $this->section->getNewsSection()->getWebserviceFeedUrl();
        $client = new nusoap_client($wsdl, 'wsdl');

        $id = $request->getParameter('id', false);

        if(!$id){
            return $this->renderText('No se ha encontrado el contenido solicitado.');
        }
        $param = array('id' => $id);
        $this->content = $client->call('WSGetNews', $param);

        $this->updateStatisticsVisits($request, $this->portal, null, null, null, true);
    }

    protected function setCommentsPagerAndForm(sfWebRequest $request){
        $this->pager = new sfDoctrinePager(
            'EmsContent',
            $this->portal->getMaxCommentsPerPage()
        );
        $this->pager->setQuery($this->content->getEnabledAndApprovedCommentsQuery());
        $this->pager->setPage($request->getParameter('page', 1));
        $this->pager->init();

        $comment = new EmsComment();
        $comment->setContent($this->content);

        $this->form = new EmsCommentForm($comment);
    }

    public function executeRenderContentUnavailable(sfWebRequest $request)
    {
        $this->content = $this->getRoute()->getObject();
        
        $this->getUserAgentCapabilities();

        $this->hasBigScreen = $this->hasBigScreen();

        $this->section = $this->content->getSection();

        $this->portal = $this->section->getPortal();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }
    }

    public function executeRenderSectionUnavailable(sfWebRequest $request) {
        $this->section = $this->getRoute()->getObject();

        $this->getUserAgentCapabilities();

        $this->hasBigScreen = $this->hasBigScreen();

        $this->portal = $this->section->getPortal();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }
    }

    public function executeRenderPortalUnavailable(sfWebRequest $request) {
        $this->portal = $this->getRoute()->getObject();

        $this->getUserAgentCapabilities();

        $this->hasBigScreen = $this->hasBigScreen();

        $this->section = $this->portal->getHomeSection();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }
    }

    public function executeDownload(sfWebRequest $request)
    {
        $this->content = $this->getRoute()->getObject();

        $this->section = $this->content->getSection();

        $this->portal = $this->section->getPortal();

        $this->getUserAgentCapabilities();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        $routing = sfContext::getInstance()->getRouting();

        if(!$this->content->getIsEnabled() || !$this->content->getPublished()){
            $this->redirect($routing->generate('render_content_unavailable', $this->content));
        }

        if(!$this->section->getIsEnabled() || !$this->section->getPublished()){
            $this->redirect($routing->generate('render_section_unavailable', $this->section));
        }

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }

        $valid = false;

        if($this->validateContentAvailabilityForUser($this->content) !== false){
            switch ($this->section->getDownloadSection()->getDownloadCondition()){
                case 'register':
                    $is_authenticated = $this->getUser()->getAttribute('is_authenticated', false);
                    if (!$is_authenticated) {
                        $register_section = $this->portal->getRegisterSection();

                        if($request->isMethod('get')) {
                            $this->redirect($routing->generate('render_section',$register_section).
                                    '?for_user_autenthication=1&for_download=1&content_id='.$this->content->getId());
                        } elseif($request->isMethod('post')) {
                            $elementForm = $this->portal->getRegisterSection()->getRegisterSection()->getRegisterFormElement();

                            $form = $this->createUserAuthenticationForm($elementForm);

                            $data = $request->getParameter($form->getName());

                            $form->bind($data);

                            $valid = $form->isValid();

                            if($valid) {
                                if($elementForm->getForm()->getUsesExternalFeed()){
                                    $wsdl = $elementForm->getForm()->getWebserviceUrl();
                                    $client = new nusoap_client($wsdl, 'wsdl');
                                    $key_field_value = $data['Values']['0']['value'];
                                    $param = array('key_field' => $key_field_value);
                                    $user_exists = $client->call('WSSearch', $param);
                                } else {
                                    $key_field = $this->portal->getRegisterSection()->
                                        getRegisterSection()->getRegisterFormElement()->getForm()->getKeyField();

                                    $value = Doctrine::getTable('EmsValue')
                                        ->findByFieldIdAndValue($key_field->getId(),$data['Values']['0']['value']);

                                    $user_exists = $value->count();
                                }

                                if($user_exists) {
                                    $this->getUser()->setAttribute('is_authenticated', true);
                                    $this->getUser()->setAttribute('key', $data['Values']['0']['value']);
                                    $this->updateStatisticsDownloads($request, $this->getUser()->getAttribute('key'), 'Registro', $this->portal, $this->content);
                                    $this->prepareForDownload($this->portal, $this->content);
                                } else {
                                    $this->redirect($routing->generate('render_section',
                                            $register_section).'?for_download=1&content_id='.$this->content->getId().
                                            '&key_value='.$data['Values']['0']['value']);
                                }
                            } else {
                                $this->getUserAgentCapabilities();

                                $this->hasBigScreen = $this->hasBigScreen();

                                $this->section = $register_section;

                                if($this->section->getUsesHeader()){
                                    $this->getHeaderElements();
                                }

                                if($this->section->getUsesFooter()){
                                    $this->getFooterElements();
                                }

                                $this->elements = $this->getSectionElements();

                                $this->for_download = true;

                                $this->for_user_autenthication = true;

                                foreach ($this->elements as $key => $element){
                                    if($element->getType()->getType() == 'Form'){
                                        unset ($this->elements[$key]);
                                        $this->form = $form;
                                        $this->form_position = $key;
                                        break;
                                    }
                                }
                                $this->setTemplate('renderSection');
                            }
                        }
                    } else {
                        $valid = true;
                        $this->updateStatisticsDownloads($request, $this->getUser()->getAttribute('key'), 'Registro', $this->portal, $this->content);
                        $this->prepareForDownload($this->portal, $this->content);
                    }
                    break;
                case 'code':
                    $valid = true;
                    $this->updateStatisticsDownloads($request, 'code', 'código', $this->portal, $this->content);
                    $this->prepareForDownload($this->portal, $this->content);
                    break;
                default:
                    $valid = true;
                    $this->updateStatisticsDownloads($request, 'libre', 'libre',$this->portal, $this->content);
                    $this->prepareForDownload($this->portal, $this->content);
                    break;
            }
            if($valid){
                return sfView::NONE;
            }
        } else {
            $this->hasBigScreen = $this->hasBigScreen();

            if($this->section->getUsesHeader()){
                $this->getHeaderElements();
            }

            if($this->section->getUsesFooter()){
                $this->getFooterElements();
            }
            $this->setTemplate('renderContentFailure');
        }
    }

    /**
     * Check if there is a content that fits the capabilities of the user device and return its filename (string),
     * otherwise returns false
     * @param EmsContent $content
     * @return mixed
     */
    protected function validateContentAvailabilityForUser(EmsContent $content){
        $filename = '';

        switch ($content->getType()->getType()) {
            case 'Image':
                $best = $this->content->getImage()->getBestFitImage(
                            $this->capabilitiesForRender['resolution_width'], $this->capabilitiesForRender['resolution_height']);
                if($this->capabilitiesForRender['jpg'] && $best){
                    $filename = $best->getFile();
                }
                break;
            case 'Sound':
                if($this->capabilitiesForRender['mp3']){
                    $filename = $content->getSound()->getFile();
                }
                break;
            case 'Video':
                if($this->capabilitiesForRender['playback_3gpp'] && $this->capabilitiesForRender['playback_mp4']){
                    $filename = $content->getVideo()->getFile();
                }
                break;
            default:
                break;
        }

        return $filename == '' ? false : $filename;
        
    }

    protected function prepareForDownload(EmsPortal $portal, EmsContent $content)
    {
        $this->getUserAgentCapabilities();
        
        $path = '';
        $ext = '';
        $fielname = $this->validateContentAvailabilityForUser($content);

        if($fielname !== false){
            switch ($content->getType()->getType()) {
                case 'Image':
                    $path = sfConfig::get('sf_upload_dir').'/portal_'.$portal->getId().'/images/'.$filename;
                    $this->getResponse()->setHttpHeader('Content-Type', 'image/jpeg');
                    $ext = '.jpg';
                    break;
                case 'Sound':
                    $path = sfConfig::get('sf_upload_dir').'/portal_'.$portal->getId().'/sounds/'.$filename;
                    $this->getResponse()->setHttpHeader('Content-Type', 'audio/mp3');
                    $ext = '.mp3';
                    break;
                case 'Video':
                    $path = sfConfig::get('sf_upload_dir').'/portal_'.$portal->getId().'/videos/'.$fielname;
                    $this->getResponse()->setHttpHeader('Content-Type', 'video/3gp');
                    $ext = '.3gp';
                    break;
                default:
                    break;
            }
        } else {
            $this->setTemplate('renderContentFailure');
        }

        // block any attempt to the filesystem
        if ($path != ''){
        // check that file exists and is readable
            if (file_exists($path) && is_readable($path)) {
                // get the file size and send the http headers
                $size = filesize($path);
                $this->getResponse()->setHttpHeader('Content-Length', $size);
                $this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename='.$content->getTitle().$ext);
                $this->getResponse()->setHeaderOnly(true);
                $this->getResponse()->send();

                // open the file in binary read-only mode
                // display the error messages if the file can´t be opened
                readfile($path);
            }
        }
    }

    protected function updateStatisticsVisits(sfWebRequest $request, EmsPortal $portal, EmsSection $section = null, EmsContent $content = null, $capabilities = array(), $is_external = false)
    {
        $statistic = new EmsStatisticsVisits();

        $statistic->setSession(session_id());
        $statistic->setPortal($portal);
        
        if(is_null($section)){
            $statistic->setSectionId(null);
        } else {
            $statistic->setSection($section);
        }
        
        if(is_null($content)){
            $statistic->setContentId(null);
        } else {
            $statistic->setContent($content);
        }

        if(!is_array($capabilities) || !count($capabilities)){
            $this->getUserAgentCapabilities();
            $capabilities = $this->capabilitiesForRender;
        }

        $statistic->setIsExternal($is_external);
        $statistic->setDeviceBrandName($capabilities['brand_name']);
        $statistic->setDeviceModelName($capabilities['model_name']);
        $statistic->setDeviceUserAgent($request->getHttpHeader('User-Agent'));

        $statistic->save();

    }

    /*
     * Esta función es para guardar las estadisticas de las descargas de los contenidos.
     * será temporal.
     */
    protected function updateStatisticsDownloads(sfWebRequest $request, $identifier, $condition, EmsPortal $portal, EmsContent $content, $capabilities = array())
    {
        $statistic = new EmsStatisticsDownloads();

        $statistic->setSession(session_id());
        $statistic->setIdentifier($identifier);
        $statistic->setDownloadCondition($condition);
        $statistic->setPortal($portal);
        $statistic->setContent($content);

        if(!is_array($capabilities) || !count($capabilities)){
            $this->getUserAgentCapabilities();
            $capabilities = $this->capabilitiesForRender;
        }

        $statistic->setDeviceBrandName($capabilities['brand_name']);
        $statistic->setDeviceModelName($capabilities['model_name']);
        $statistic->setDeviceUserAgent($request->getHttpHeader('User-Agent'));

        $statistic->save();
    }

    public function executeProcessComment(sfWebRequest $request)
    {
        $this->getUserAgentCapabilities();

        $this->content = $this->getRoute()->getObject();

        $this->section = $this->content->getSection();

        $this->portal = $this->section->getPortal();

        $this->redirectIfNotWirelessDevice($this->portal, $this->capabilitiesForRender['is_wireless_device']);

        $this->setCommentsPagerAndForm($request);

        $this->valid = $this->processCommentForm($request, $this->form);

//        $routing = sfContext::getInstance()->getRouting();
//
//        $this->redirect($routing->generate('render_content', $this->content));

        if(!$this->content->getIsEnabled() || !$this->content->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_content_unavailable', $this->content));
        }

        if(!$this->section->getIsEnabled() || !$this->section->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_section_unavailable', $this->section));
        }

        if(!$this->portal->getIsEnabled() || !$this->portal->getPublished()){
            $routing = sfContext::getInstance()->getRouting();
            $this->redirect($routing->generate('render_portal_unavailable', $this->portal));
        }

        $this->hasBigScreen = $this->hasBigScreen();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        if($this->content->getType()->getType() == 'Image'){
            $this->best = $this->content->getImage()->getBestFitImage(
                    $this->capabilitiesForRender['resolution_width'], $this->capabilitiesForRender['resolution_height']);
            if(!$this->capabilitiesForRender['jpg'] || !$this->best){
                $this->setTemplate('renderContentFailure');
            }
        }

        $this->setTemplate('renderContent');
    }

    protected function processCommentForm(sfWebRequest $request, sfForm $form)
    {
        $form->bind($request->getParameter($form->getName()));

        $valid = $form->isValid();
        if ($valid){
            $comment = $form->save();
        }

        return $valid;
    }

    public function executeProcessRegister(sfWebRequest $request)
    {
        $this->element = $this->getRoute()->getObject();

        $this->section = $this->element->getSection();

        $this->forward404Unless($this->section->getType()->getType() == 'Register');

        $this->elements = $this->getSectionElements();

        $this->prepareRegisterSection(false);

        $this->getUserAgentCapabilities();

        $this->hasBigScreen = $this->hasBigScreen();

        $this->portal = $this->section->getPortal();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        $this->contents = $this->section->getContentsForRender();

        $this->for_download = $request->getParameter('for_download',false);

        if($this->for_download){
            $this->content = Doctrine::getTable('EmsContent')->find($request->getParameter('content_id'));
        }

        $this->server_problem = $this->processForm($request, $this->form);

        $this->setTemplate('renderSection');
    }

    protected function processForm(sfWebRequest $request, sfForm $form)
    {
        $server_problem = false;
        $form->bind($request->getParameter($form->getName()));
        if ($form->isValid())
        {            
            $routing = sfContext::getInstance()->getRouting();

            if($this->elementForm->getForm()->getUsesExternalFeed()){
                $wsdl = $this->elementForm->getForm()->getWebserviceUrl();
                $client = new nusoap_client($wsdl, 'wsdl');

                $param = array();

                foreach ($form->getObject()->getValues() as $key => $value) {
                    $param[$value->getField()->getTitleSlug()] = $value->getValue();
                }
                
                $result = $client->call('WSInsertUser', $param);

                if($result){
                    $register = $form->save();
                } else {
                    $server_problem = true;
                }
            } else {
                $register = $form->save();
            }

            if(!$server_problem){
                if($request->getParameter('for_download',false)){
                    $this->getUser()->setAttribute('is_authenticated', true);
                    $this->getUser()->setAttribute('key', $register->getKeyFieldValue());
                    $this->forward404Unless($content = Doctrine::getTable('EmsContent')->find($request->getParameter('content_id')));
                    $this->redirect($routing->generate('render_content', $content));
                } else {
                    $this->redirect($routing->generate('render_homesection', $this->portal));
                }
            }
        }

        return $server_problem;
    }

    public function executeServiceButtonAction(sfWebRequest $request)
    {
        $this->getUserAgentCapabilities();
        
        $button = $this->getRoute()->getObject();

        $this->forward404Unless($this->content = Doctrine::getTable('EmsContent')->find($request->getParameter('content_id')));

        $this->section = $this->content->getSection();

        $this->portal = $this->section->getPortal();

        if($this->section->getUsesHeader()){
            $this->getHeaderElements();
        }

        if($this->section->getUsesFooter()){
            $this->getFooterElements();
        }

        if($this->portal->getUsesContentComments()){
            $this->setCommentsPagerAndForm($request);
        }

        $routing = sfContext::getInstance()->getRouting();

        switch ($button->getType()->getType()) {
            case 'Facebook':
                return $this->redirect($button->getType()->getUrl().$routing->generate('render_content',$this->content,true));
                break;
            case 'Twitter':
                $message = $this->prepareMessage($button->getMessage(), $this->content, $this->portal);
                return $this->redirect($button->getType()->getUrl().$message);
                break;
            case 'Email':
                $this->form = new ServButtonEmailRequestForm();
                $this->button = $button;
                $this->setTemplate('requestForm');
                if($request->isMethod('post')) {
                    $this->form->bind($request->getParameter($this->form->getName()));
                    if($this->form->isValid()){
                        $this->sendEmail($this->portal, $this->content, $button, $this->form->getValue('email'));
                        $this->redirect($routing->generate('render_content',$this->content));
                    }
                }
                break;
            case 'SMS':
                $form = new ServButtonPhoneRequestForm();
                if($request->isMethod('get')){
                    return $this->renderPartial('requestForm',
                            array(
                                'form' => $form,'button' => $button,'content' => $this->content,
                                'section' => $this->section, 'portal' => $this->portal,
                                'headerObjects' => $this->headerObjects, 'footerObjects' => $this->footerObjects
                            ));
                } elseif($request->isMethod('post')) {
                    $form->bind($request->getParameter($form->getName()));
                    if($form->isValid()){
                        return $this->renderPartial('requestForm',
                                array(
                                    'form' => $form,'button' => $button,'content' => $this->content,
                                    'section' => $this->section, 'portal' => $this->portal,
                                    'headerObjects' => $this->headerObjects, 'footerObjects' => $this->footerObjects
                                ));
                    } else {
                        return $this->renderPartial('requestEmailForm',
                                array(
                                    'form' => $form,'button' => $button,'content' => $this->content,
                                    'section' => $this->section, 'portal' => $this->portal,
                                    'headerObjects' => $this->headerObjects, 'footerObjects' => $this->footerObjects
                                ));
                    }
                }
                break;
            default:
                return sfView::NONE;
                break;
        }
    }

    protected function prepareMessage($message, EmsContent $content, EmsPortal $portal)
    {
        $routing = sfContext::getInstance()->getRouting();

        $portal_shorturl = $this->shortenURL($routing->generate('render_homesection',$portal,true));

        $content_shorturl = $this->shortenURL($routing->generate('render_content',$content,true));

        $search = array('%cont%','%portal%','%c-url%','%p-url%');

        $replace = array($content->getTitle(), $portal->getTitle(), $content_shorturl, $portal_shorturl);

        return str_replace($search, $replace, $message);
    }

    protected function shortenURL($url)
    {
        $urlshort = "http://api.bit.ly/v3/shorten?login=equilibriomcms&apiKey=R_bba6ae9f13bbae92691823c0fffdbd6f&longUrl=".
                        urlencode($url)."&format=json";
        $handle = fopen($urlshort,"r");
        $suri = "";
        if ($handle) {
            while (($buffer = fgets($handle, 4096)) !== false) {
                $suri .=  $buffer;
            }
            if (!feof($handle)) {
                echo "Error: unexpected fgets() fail\n";
            }
            fclose($handle);
        }
        $uri = json_decode($suri,true);

        return $uri['data']['url'];
    }

    protected function sendEmail(EmsPortal $portal, EmsContent $content, EmsServiceButton $button, $email)
    {
        $body = $this->prepareMessage($button->getMessage(), $content, $portal);
        
        $message = Swift_Message::newInstance()
            ->setFrom($portal->getEmail())
            ->setTo($email)
            ->setSubject($portal->getTitle().' - '.$content->getTitle())
            ->setBody(html_entity_decode($body), 'text/html', 'utf-8');

        $this->getMailer()->send($message);
    }

    protected function getSectionElements()
    {
        $elements = $this->section->getElementsForRender();

        foreach ($elements as $element) {
            switch ($element->getType()->getType()) {
                case 'Banner':
                    if($this->capabilitiesForRender['jpg']){
                        $best = $element->getBanner()->getBestFitImage($this->capabilitiesForRender['resolution_width']);
                        if($best){
                            $element->getBanner()->setImageForRender($best);
                        } else {
                            $element->getBanner()->setImageForRender();
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        return $elements;
    }

    protected function getHeaderElements()
    {
        $elements = $this->portal->getHeader()->getElements();

        $this->headerObjects = array();

        foreach ($elements as $element) {
            if($element->getPublished()){
                switch ($element->getType()->getType()) {
                    case 'Banner':
                        if($this->capabilitiesForRender['jpg'] && $this->portal->getHeader()->getUsesBanner()){
                            $best = $element->getBanner()->getBestFitImage($this->capabilitiesForRender['resolution_width']);
                            if($best){
                                $element->getBanner()->setImageForRender($best);
                            } else {
                                $element->getBanner()->setImageForRender();
                            }
                            $this->headerObjects[$element->getPosition()] = $element;
                        }
                        break;
                    case 'Menu':
                        if($this->portal->getHeader()->getUsesMenu()){
                            $this->headerObjects[$element->getPosition()] = $element;
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        ksort($this->headerObjects);
    }

    protected function getFooterElements()
    {
        $elements = $this->portal->getFooter()->getElements();

        $this->footerObjects = array();

        foreach ($elements as $element) {
            switch ($element->getType()->getType()) {
                case 'Banner':
                   if($this->capabilitiesForRender['jpg'] && $this->portal->getFooter()->getUsesBanner()){
                        $best = $element->getBanner()->getBestFitImage($this->capabilitiesForRender['resolution_width']);
                        if($best){
                            $element->getBanner()->setImageForRender($best);
                        } else {
                            $element->getBanner()->setImageForRender();
                        }
                        $this->footerObjects[$element->getPosition()] = $element;
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
